﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using Newtonsoft.Json;
using System.IO;
using System.Collections;

public static class GoogleTranslator {
    /// <summary>
    /// JSON Response Class.
    /// </summary>
    public class TranslationResponse {
        [JsonProperty("responseData")]
        public Translation Data { get; set; }

        [JsonProperty("responseDetails")]
        public string Details { get; set; }

        [JsonProperty("responseStatus")]
        public int Status { get; set; }
    }

    /// <summary>
    /// JSON Translation Response.
    /// </summary>
    public class Translation {
        private string translatedText;
        [JsonProperty("translatedText")]
        public string TranslatedText {
            get { return translatedText; }
            set { translatedText = Utils.HtmlDecode(value); }
        }
    }

    /// <summary>
    /// Translates a string using the specified language pair
    /// See http://code.google.com/intl/de/apis/ajaxlanguage/documentation/#SupportedPairs and  http://code.google.com/intl/de/apis/ajaxlanguage/documentation/reference.html for a list of supported languages
    /// </summary>
    /// <param name="text">The text to translate.</param>
    /// <param name="sourceLanguage">The source language.</param>
    /// <param name="destinationLanguage">The destination language.</param>
    /// <returns>
    /// A response containing either the translated string or a responseStatus code with responseDetails
    /// </returns>
    public static TranslationResponse Translate(string text, string sourceLanguage, string destinationLanguage) {
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(string.Format("http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q={0}&langpair={1}%7C{2}", System.Uri.EscapeDataString(text), sourceLanguage, destinationLanguage));
        req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 2.0.50727)";
        req.KeepAlive = true;
        WebResponse response = req.GetResponse();
        StreamReader streamReader = new StreamReader(response.GetResponseStream());

        TranslationResponse translationResponse;
        string responseContents = string.Empty;
        try {
            responseContents = streamReader.ReadToEnd();
            StringReader responseReader = new StringReader(responseContents);
            JsonSerializer serializer = new JsonSerializer();
            translationResponse = (TranslationResponse)serializer.Deserialize(responseReader, typeof(TranslationResponse));
        } catch(Exception ex) {
            translationResponse = new TranslationResponse();
            translationResponse.Status = 500;
            translationResponse.Details = string.Format("Error parsing response: {0} - {1}", responseContents, ex.Message);
        }
        return translationResponse;
    }

    /// <summary>
    /// Retrieves a Google translate code for a specified .NET CultureInfo.Name code. This is usually the same but sometimes varies. An empty string is returned if the code is unsupported by Google Translate.
    /// </summary>
    /// <param name="code">The CultureInfo.Name of a language.</param>
    /// <returns></returns>
    public static string DotNetCode2GoogleCode(string code) {
        return code.Length > 2 ? code.Substring(0, 2) : code;
    }

    /// <summary>
    /// Retrieves a Google translate code for a specified ISO 639-1 code. This is usually the same but sometimes varies. An empty string is returned if the code is unsupported by Google Translate.
    /// </summary>
    /// <param name="isoCode">The ISO 639-1 code.</param>
    /// <returns>The equivalent Google Translate language code, or an empty string if the code is unsupported by Google Translate.</returns>
    public static string ISOCode2GoogleCode(string isoCode) {
        string googleCode = string.Empty;
        switch(isoCode) { //some .NET peculiarities
            case "he":
                googleCode = "iw";
                break;
            case "pt":
                googleCode = "pt-PT";
                break;
            case "zh-CHS":
                googleCode = "zh-CN";
                break;
            case "zh-CHT":
                googleCode = "zh-TW";
                break;
            default: // only assign the code if the language is supported (null = hide the Google button)
                if(GoogleSupportedLanguages.ContainsKey(isoCode)) {
                    googleCode = isoCode;
                }
                break;
        }
        return googleCode;
    }

    /// <summary>
    /// Languages supported by Google's Translate API. Key = Code, Value = English Name
    /// See http://code.google.com/intl/de/apis/ajaxlanguage/documentation/#SupportedPairs for an updated list
    /// </summary>
    public static Dictionary<string, string> GoogleSupportedLanguages = new Dictionary<string, string>() {
            { "sq", "Albanian" },
        { "ar", "Arabic" },
        { "bg", "Bulgarian" },
        { "ca", "Catalan" },
        { "zh", "Chinese" },
        { "zh-CN", "Chinese (Simplified)" },
        { "zh-TW", "Chinese (Traditional)" },
        { "hr", "Croatian" },
        { "cs", "Czech" },
        { "da", "Danish" },
        { "nl", "Dutch" },
        { "en", "English" },
            { "et", "Estonian" },
        { "tl", "Filipino" },
        { "fi", "Finnish" },
        { "fr", "French" },
            { "gl", "Galician" },
        { "de", "German" },
        { "el", "Greek" },
        { "iw", "Hebrew" },
        { "hi", "Hindi" },
            { "hu", "Hungarian" },
        { "id", "Indonesian" },
        { "it", "Italian" },
        { "ja", "Japanese" },
        { "ko", "Korean" },
        { "lv", "Latvian" },
        { "lt", "Lithuanian" },
            { "mt", "Maltese" },
        { "no", "Norwegian" },
        { "pl", "Polish" },
        { "pt-PT", "Portuguese" },
        { "ro", "Romanian" },
        { "ru", "Russian" },
        { "es", "Spanish" },
        { "sr", "Serbian" },
        { "sk", "Slovak" },
        { "sl", "Slovenian" },
        { "sv", "Swedish" },
            { "th", "Thai" },
            { "tr", "Turkish" },
        { "uk", "Ukranian" },
        { "vi", "Vietnamese"}
    };
}